package proxy

import (
	"bufio"
	"context"
	"fmt"
	"net"
	"net/http"
	"sync"
	"time"

	"network-firewall-go/internal/cert"
	"network-firewall-go/internal/database"
	"network-firewall-go/internal/rules"
	"network-firewall-go/internal/types"
	"network-firewall-go/internal/websocket"
)

// Server 代理服务器
type Server struct {
	port      int
	listener  net.Listener
	isRunning bool
	ctx       context.Context
	cancel    context.CancelFunc
	wg        sync.WaitGroup
	mu        sync.RWMutex

	// 连接管理
	activeConnections map[net.Conn]bool
	connMu            sync.RWMutex

	// 依赖注入
	db          *database.Manager
	rulesEngine *rules.Engine
	stats       *ServerStats

	config      *types.ProxyConfig
	certManager *cert.Manager
	wsServer    *websocket.Server
}

// NewServer 创建新的代理服务器
func NewServer(port int, db *database.Manager, rulesEngine *rules.Engine, config *types.ProxyConfig, certManager *cert.Manager, wsServer *websocket.Server) *Server {
	return &Server{
		port:              port,
		db:                db,
		rulesEngine:       rulesEngine,
		config:            config,
		certManager:       certManager,
		wsServer:          wsServer,
		stats:             &ServerStats{},
		activeConnections: make(map[net.Conn]bool),
	}
}

// Start 启动代理服务器
func (s *Server) Start() error {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.isRunning {
		return fmt.Errorf("代理服务器已在运行")
	}

	s.ctx, s.cancel = context.WithCancel(context.Background())

	// 监听TCP端口
	listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", s.port))
	if err != nil {
		return fmt.Errorf("监听端口失败: %v", err)
	}

	s.listener = listener
	s.isRunning = true

	fmt.Printf("🚀 代理服务器启动成功，监听地址: 0.0.0.0:%d\n", s.port)

	// 启动连接处理循环
	s.wg.Add(1)
	go s.acceptConnections()

	return nil
}

// Stop 停止代理服务器
func (s *Server) Stop() error {
	s.mu.Lock()
	defer s.mu.Unlock()

	if !s.isRunning {
		return nil
	}

	fmt.Printf("🛑 正在停止代理服务器...\n")

	// 取消上下文
	if s.cancel != nil {
		s.cancel()
	}

	// 关闭监听器
	if s.listener != nil {
		s.listener.Close()
	}

	s.isRunning = false

	// 强制关闭所有活跃连接
	s.closeAllConnections()

	// 设置最大等待时间为5秒
	done := make(chan struct{})
	go func() {
		s.wg.Wait()
		close(done)
	}()

	select {
	case <-done:
		fmt.Printf("✅ 代理服务器已停止\n")
	case <-time.After(5 * time.Second):
		fmt.Printf("⚠️ 代理服务器停止超时，强制结束\n")
	}

	return nil
}

// IsRunning 检查服务器是否正在运行
func (s *Server) IsRunning() bool {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return s.isRunning
}

// acceptConnections 接受连接的主循环
func (s *Server) acceptConnections() {
	defer s.wg.Done()

	for {
		select {
		case <-s.ctx.Done():
			return
		default:
		}

		// 设置接受超时
		if tcpListener, ok := s.listener.(*net.TCPListener); ok {
			tcpListener.SetDeadline(time.Now().Add(1 * time.Second))
		}

		conn, err := s.listener.Accept()
		if err != nil {
			// 检查是否是超时错误或上下文取消
			if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
				continue
			}
			select {
			case <-s.ctx.Done():
				return
			default:
				fmt.Printf("❌ 接受连接失败: %v\n", err)
				continue
			}
		}

		// 为每个连接启动处理goroutine
		s.wg.Add(1)
		go s.handleConnection(conn)
	}
}

// handleConnection 处理单个连接
func (s *Server) handleConnection(conn net.Conn) {
	defer s.wg.Done()
	defer conn.Close()

	// 添加到活跃连接管理
	s.addConnection(conn)
	defer s.removeConnection(conn)

	// 添加连接统计
	s.stats.addConnection()
	defer s.stats.removeConnection()

	// 设置较短的连接超时，便于快速停止
	conn.SetReadDeadline(time.Now().Add(10 * time.Second))

	// 读取HTTP请求
	br := bufio.NewReader(conn)
	req, err := http.ReadRequest(br)
	if err != nil {
		// 检查是否是上下文取消导致的错误，减少日志噪音
		select {
		case <-s.ctx.Done():
			return // 服务器正在停止，静默返回
		default:
			fmt.Printf("❌ 读取请求失败: %v\n", err)
		}
		return
	}

	fmt.Printf("🔍 收到请求: %s %s\n", req.Method, req.URL.String())

	// 根据请求方法处理
	if req.Method == http.MethodConnect {
		s.handleConnectRequestTCP(conn, req)
	} else {
		s.handleHTTPRequestTCP(conn, req)
	}
}

// GetStatus 获取服务器状态
func (s *Server) GetStatus() *types.ProxyStatus {
	s.mu.RLock()
	defer s.mu.RUnlock()

	status := s.stats.GetStatus()
	status.Running = s.isRunning
	status.Port = s.port
	if s.config != nil {
		status.InterceptHTTPS = s.config.InterceptHTTPS
	}

	return status
}

// addConnection 添加活跃连接
func (s *Server) addConnection(conn net.Conn) {
	s.connMu.Lock()
	defer s.connMu.Unlock()
	s.activeConnections[conn] = true
}

// removeConnection 移除活跃连接
func (s *Server) removeConnection(conn net.Conn) {
	s.connMu.Lock()
	defer s.connMu.Unlock()
	delete(s.activeConnections, conn)
}

// closeAllConnections 强制关闭所有活跃连接
func (s *Server) closeAllConnections() {
	s.connMu.Lock()
	defer s.connMu.Unlock()

	fmt.Printf("🔌 正在关闭 %d 个活跃连接...\n", len(s.activeConnections))

	for conn := range s.activeConnections {
		if conn != nil {
			conn.Close()
		}
	}

	// 清空连接映射
	s.activeConnections = make(map[net.Conn]bool)
}
